﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using LuckDraw.Models;
using LuckDraw.Utils;
using LuckDraw.Views;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Reflection;
using System.Security.RightsManagement;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace LuckDraw.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        private List<RoundModel> numberdata = null;
        public MainViewModel()
        {
            roundModelList = new ObservableCollection<RoundModel>();
            numberdata = new List<RoundModel>();
            PublicMethd.MaxWillNumber = int.Parse(INIHelper.GetIniString("抽奖配置", "最大号码", "160", PublicMethd.ConfigFileName));
            string numberStr = INIHelper.GetIniString("抽奖配置", "去掉号码", "", PublicMethd.ConfigFileName);
            if (!string.IsNullOrEmpty(numberStr))
            {
                var data = numberStr.Trim().Split(',');
                if (data != null)
                {
                    PublicMethd.RemoveNumber = new List<int>();
                    for (int i = 0; i < data.Count(); i++)
                    {
                        string item = data[i].Trim();
                        if (!PublicMethd.RemoveNumber.Contains(int.Parse(item)))
                            PublicMethd.RemoveNumber.Add(int.Parse(item));
                    }
                }
            }
            Init();
        }
        private void Init()
        {
            RBIsEnabled = true;
            contentStr = "开抽";
            IsThirdPrize = true;
            IsSecondPrize = false;
            IsFirstPrize = false;
            IsGrandPrize = false;
            PrizeTypeChecked("ThirdPrize");
            LuckDrawCommand = new RelayCommand(LuckDraw);
            PrizeTypeCommand = new RelayCommand<string>(PrizeTypeChecked);
            ConfigCommand = new RelayCommand(() =>
            {
                UpdateRemovNumber updateRemovNumber = new UpdateRemovNumber();
                var win = Application.Current.MainWindow;
                if (win != null)
                    updateRemovNumber.Owner = Application.Current.MainWindow;
                updateRemovNumber.ShowDialog();
                if(updateRemovNumber.DialogResult==true)
                    SetNumberData();
            });
            SetNumberData();
        }
        private void SetNumberData()
        {
            numberdata = new List<RoundModel>();
            for (int i = 0; i <= PublicMethd.MaxWillNumber; i++)
            {
                RoundModel roundModel = new RoundModel();

                roundModel.Number = i + 1;
                if (roundModel.Number <= 20)
                    roundModel.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#E60012"));
                else if (roundModel.Number <= 40)
                    roundModel.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#F18101"));
                else if (roundModel.Number <= 60)
                    roundModel.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FDD100"));
                else if (roundModel.Number <= 80)
                    roundModel.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#8FC320"));
                else if (roundModel.Number <= 100)
                    roundModel.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#00A0EA"));
                else if (roundModel.Number <= 120)
                    roundModel.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#EC6CA5"));
                else if (roundModel.Number <= 140)
                    roundModel.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#9F0382"));
                else if (roundModel.Number <= 147)
                    roundModel.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#975835"));
                else if (roundModel.Number <= 160)
                    roundModel.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#975835"));
                else if (roundModel.Number <= PublicMethd.MaxWillNumber)
                    roundModel.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#975835"));

                if (roundModel.Number >= 100)
                {
                    roundModel.FontSize = 34;
                }
                else if (roundModel.Number <= 9)
                    roundModel.FontSize = 46;
                else
                    roundModel.FontSize = 42;
                if (PublicMethd.RemoveNumber.Where(p => p == roundModel.Number).Count() == 0)
                {
                    numberdata.Add(roundModel);
                }
            }
        }
        private ObservableCollection<RoundModel> roundModelList { get; set; }
        public ObservableCollection<RoundModel> RoundModelList
        {
            get { return roundModelList; }
            set { roundModelList = value; RaisePropertyChanged(); }
        }
        private bool isGrandPrize { get; set; }
        /// <summary>
        /// 特等奖
        /// </summary>
        public bool IsGrandPrize { get { return isGrandPrize; } set { isGrandPrize = value; RaisePropertyChanged(); } }
        private bool isFirstPrize { get; set; }
        /// <summary>
        /// 一等奖
        /// </summary>
        public bool IsFirstPrize { get { return isFirstPrize; } set { isFirstPrize = value; RaisePropertyChanged(); } }
        private bool isSecondPrize { get; set; }
        /// <summary>
        /// 二等奖
        /// </summary>
        public bool IsSecondPrize { get { return isSecondPrize; } set { isSecondPrize = value; RaisePropertyChanged(); } }
        private bool isThirdPrize { get; set; }
        /// <summary>
        /// 三等奖
        /// </summary>
        public bool IsThirdPrize { get { return isThirdPrize; } set { isThirdPrize = value; RaisePropertyChanged(); } }
        private bool rBIsEnabled { get; set; }
        public bool RBIsEnabled { get { return rBIsEnabled; } set { rBIsEnabled = value; RaisePropertyChanged(); } }

        public RelayCommand ConfigCommand { get; set; }
        public RelayCommand<string> PrizeTypeCommand { get; set; }
        private string _PrizeType = "GrandPrize";
        private void PrizeTypeChecked(string PrizeType)
        {
            _PrizeType = PrizeType;
            RoundModelList.Clear();
            switch (PrizeType)
            {
                case "GrandPrize":
                    for (int i = 0; i < PublicMethd.GrandPrize; i++)
                    {
                        RoundModelList.Add(GetDefalut());
                    }
                    break;
                case "FirstPrize":
                    for (int i = 0; i < PublicMethd.FirstPrize; i++)
                    {
                        RoundModelList.Add(GetDefalut());
                    }
                    break;
                case "SecondPrize":
                    for (int i = 0; i < PublicMethd.SecondPrize; i++)
                    {
                        RoundModelList.Add(GetDefalut());
                    }
                    break;
                case "ThirdPrize":
                    for (int i = 0; i < PublicMethd.ThirdPrize; i++)
                    {
                        RoundModelList.Add(GetDefalut());
                    }
                    break;
                default:
                    break;
            }
        }
        private RoundModel GetDefalut()
        {
            RoundModel roundModel = new RoundModel();
            roundModel.Number = 0;
            roundModel.FontSize = 40;
            roundModel.Background = Brushes.White;
            return roundModel;
        }

        private string contentStr { get; set; }
        /// <summary>
        /// 按钮内容
        /// </summary>
        public string ContentStr { get { return contentStr; } set { contentStr = value; RaisePropertyChanged(); } }
        public RelayCommand LuckDrawCommand { get; set; }
        private bool IsStart = false;
        private void LuckDraw()
        {
            IsStart = !IsStart;
            if (IsStart)
            {
                RBIsEnabled = false;
                Start();
                ContentStr = "停止";
            }
            else
            {
                RBIsEnabled = true;
                Stop();
                ContentStr = "开始";
            }

        }

        CancellationTokenSource tokenSource;
        ManualResetEvent resetEvent;
        CancellationToken token;
        public void Start()
        {
            //tokenSource = new CancellationTokenSource();
            //resetEvent = new ManualResetEvent(true);
            //token = tokenSource.Token;
            //Task task = new Task(() =>
            //{
            //    while (IsStart)
            //    {
            //        if (token.IsCancellationRequested)
            //        {
            //            return;
            //        }
            //        resetEvent.WaitOne();
            //        try
            //        {
            //            Random rd = new Random();
            //            Application.Current.Dispatcher.Invoke(() =>
            //            {
            //                List<int> ints = new List<int>();
            //                for (int i = 0; i < RoundModelList.Count(); i++)
            //                {
            //                    //产生一个1至MaxWillNumber之间的整数
            //                    var number = rd.Next(1, PublicMethd.MaxWillNumber + 1);
            //                    if (RoundModelList.Where(p => p.Number == number).Count() == 0)
            //                        RoundModelList[i] = numberdata.FirstOrDefault(p => p.Number == number);
            //                }
            //            });
            //        }
            //        catch (Exception ex)
            //        {
            //        }
            //        Task.Delay(1);
            //    }

            //}, token);
            //task.Start();

            Task.Run(new Action(() =>
            {
                while (IsStart)
                {
                    if (!IsStart)
                        break;
                    try
                    {
                        Random rnd = new Random();
                        List<int> list = new List<int>();
                        for (int i = 0; i < 5; i++)
                        {
                            list.AddRange(GetRandomArray(rnd, PublicMethd.MaxWillNumber, RoundModelList.Count()));
                        }
                        List<int> data = list.Distinct().ToList();
                        foreach (var item in PublicMethd.RemoveNumber)
                        {
                            if (data.Where(p => p == item).Count() > 0)
                            {
                                data.Remove(item);
                            }
                        }
                        data = Disorder(RandomSort(data).ToList().ToArray()).ToList();
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            if (data.Count() >= RoundModelList.Count())
                            {
                                for (int i = 0; i < RoundModelList.Count(); i++)
                                {
                                    if (!IsStart)
                                        break;
                                    var number = data[i];
                                    var lucCount = luckNumbers.Where(p => p == number).Count();
                                    var rundList = RoundModelList.Where(p => p.Number == number).Count();
                                    if (lucCount == 0 && rundList == 0)
                                    {
                                        var model = numberdata.FirstOrDefault(p => p.Number == number);
                                        if (model != null)
                                            RoundModelList[i] = model;
                                    }
                                }
                            }
                        });
                    }
                    catch (Exception ex)
                    {
                    }
                    Task.Delay(1);
                }
            }));
        }

        public void Stop()
        {
            //resetEvent.Reset();
            //tokenSource.Cancel();
            SetWillData();
        }
        /// <summary>
        /// 把收集回来的列表打乱顺序之后返回
        /// </summary>
        /// <returns></returns>
        public IList<int> RandomSort(IList<int> ListStr)
        {
            Random rand = new Random();
            int iTarget = 0;
            int str = 0;
            for (int i = 0; i < ListStr.Count; i++)
            {
                iTarget = rand.Next(0, ListStr.Count);
                str = ListStr[i];
                ListStr[i] = ListStr[iTarget];
                ListStr[iTarget] = str;
            }
            return ListStr;
        }
        public int[] Disorder(int[] arr)
        {
            Random rand = new Random();
            int rdm, tmp;
            for (int n = arr.Count(); n > 1;)
            {
                // 生成一个`[0,n-1]` 的随机数
                rdm = rand.Next(0, n);
                n--;
                // 将这个随机数和最后一个数交换
                if (rdm != n)
                {
                    tmp = arr[rdm];
                    arr[rdm] = arr[n];
                    arr[n] = tmp;
                }
            }
            return arr;
        }
        private int GetRandomNumber(Random rnd, int minNumber, int maxNumber)
        {
            int number = 0;
            number = rnd.Next(minNumber, maxNumber + 1);
            if (PublicMethd.RemoveNumber.Where(p => p == number).Count() == 0)
            {
                return number;
            }
            return GetRandomNumber(rnd, maxNumber, minNumber);
        }
        public List<int> GetRandomArray(Random rnd, int maxNumber, int count)
        {
            List<int> list = new List<int>();//保存取出的随机数
            int[] array = new int[maxNumber];//定义初始数组
            for (int i = 0; i < maxNumber; i++)//给数组元素赋值
                array[i] = i + 1;
            for (int j = 0; j < count; j++)
            {
                int index = rnd.Next(j + 1, maxNumber + 1);
                int temp = array[index];//从数组中取出index为下标的数
                list.Add(temp);//将取出的数添加到list中
                array[index] = array[j];//将下标为j的数交换到index位置
                array[j] = temp;//将取出的数交换到j的位置
            }
            return list;
        }
        #region 中奖记录
        List<int> luckNumbers = new List<int>();
        private void SetWillData()
        {

            switch (this._PrizeType)
            {
                case "GrandPrize":
                    GrandPrizeList.ToList().ForEach((t) => { luckNumbers.Remove(t.Number); });
                    GrandPrizeList.Clear();
                    RoundModelList.ToList().ForEach(p =>
                    {
                        RoundModel roundModel = new RoundModel();
                        roundModel.Number = p.Number;
                        roundModel.FontSize = p.FontSize;
                        roundModel.Background = p.Background;
                        GrandPrizeList.Add(roundModel);
                        luckNumbers.Add(p.Number);
                    });
                    break;
                case "FirstPrize":
                    FirstPrizeList.ToList().ForEach((t) => { luckNumbers.Remove(t.Number); });
                    FirstPrizeList.Clear();
                    RoundModelList.ToList().ForEach(p =>
                    {
                        RoundModel roundModel = new RoundModel();
                        roundModel.Number = p.Number;
                        roundModel.FontSize = p.FontSize;
                        roundModel.Background = p.Background; FirstPrizeList.Add(roundModel);
                        luckNumbers.Add(p.Number);
                    });
                    break;
                case "SecondPrize":
                    if (SecondPrizeList.Count() >= 10)
                    {
                        SecondPrizeList.ToList().ForEach((t) => { luckNumbers.Remove(t.Number); });
                        SecondPrizeList.Clear();
                    }
                    RoundModelList.ToList().ForEach(p =>
                    {
                        RoundModel roundModel = new RoundModel();
                        roundModel.Number = p.Number;
                        roundModel.FontSize = p.FontSize;
                        roundModel.Background = p.Background; SecondPrizeList.Add(roundModel);
                        luckNumbers.Add(p.Number);
                    });
                    break;
                case "ThirdPrize":
                    if (ThirdPrizeList.Count() >= 20)
                    {
                        ThirdPrizeList.ToList().ForEach((t) => { luckNumbers.Remove(t.Number); });
                        ThirdPrizeList.Clear();
                    }
                    RoundModelList.ToList().ForEach(p =>
                    {
                        RoundModel roundModel = new RoundModel();
                        roundModel.Number = p.Number;
                        roundModel.FontSize = p.FontSize;
                        roundModel.Background = p.Background; ThirdPrizeList.Add(roundModel);
                        luckNumbers.Add(p.Number);
                    });
                    break;
                default:
                    break;
            }
        }
        private ObservableCollection<RoundModel> grandPrizeList { get; set; } = new ObservableCollection<RoundModel>();
        /// <summary>
        /// 特等奖
        /// </summary>
        public ObservableCollection<RoundModel> GrandPrizeList
        {
            get { return grandPrizeList; }
            set { grandPrizeList = value; RaisePropertyChanged(); }
        }
        private ObservableCollection<RoundModel> firstPrizeList { get; set; } = new ObservableCollection<RoundModel>();
        public ObservableCollection<RoundModel> FirstPrizeList
        {
            get { return firstPrizeList; }
            set { firstPrizeList = value; RaisePropertyChanged(); }
        }
        private ObservableCollection<RoundModel> secondPrizeList { get; set; } = new ObservableCollection<RoundModel>();
        public ObservableCollection<RoundModel> SecondPrizeList
        {
            get { return secondPrizeList; }
            set { secondPrizeList = value; RaisePropertyChanged(); }
        }
        private ObservableCollection<RoundModel> thirdPrizeList { get; set; } = new ObservableCollection<RoundModel>();
        public ObservableCollection<RoundModel> ThirdPrizeList
        {
            get { return thirdPrizeList; }
            set { thirdPrizeList = value; RaisePropertyChanged(); }
        }
        #endregion
    }
}
